package com.zhiche.lisa.integration.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.toolkit.CollectionUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zhiche.lisa.core.enums.TableStatusEnum;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.supports.RestfulResponse;
import com.zhiche.lisa.core.utils.HttpClientUtil;
import com.zhiche.lisa.integration.anno.AnnoUtil;
import com.zhiche.lisa.integration.controller.OTMController;
import com.zhiche.lisa.integration.dao.mapper.ImportLogHistoryMapper;
import com.zhiche.lisa.integration.dao.mapper.ImportLogMapper;
import com.zhiche.lisa.integration.dao.mapper.OrderReleaseMidMapper;
import com.zhiche.lisa.integration.dao.mapper.PushSubSystemMapper;
import com.zhiche.lisa.integration.dao.model.*;
import com.zhiche.lisa.integration.dto.order.ReleaseDTO;
import com.zhiche.lisa.integration.dto.order.ShipmentInbound;
import com.zhiche.lisa.integration.dto.order.ShipmentInfo;
import com.zhiche.lisa.integration.dto.otd.InTransitDTO;
import com.zhiche.lisa.integration.dto.otd.NewOrderReleaseMidDTO;
import com.zhiche.lisa.integration.dto.otd.OrderReleaseMidDTO;
import com.zhiche.lisa.integration.dto.tms.PodReasonDTO;
import com.zhiche.lisa.integration.inteface.otm.OtmEventService;
import com.zhiche.lisa.integration.service.OrderReleaseMidService;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 运单信息中间表 服务实现类
 * </p>
 *
 * @author hs
 * @since 2018-12-11
 */
@Service
public class OrderReleaseMidServiceImpl extends ServiceImpl<OrderReleaseMidMapper, OrderReleaseMid> implements OrderReleaseMidService {

    private static final Logger LOGGER = LoggerFactory.getLogger(OTMController.class);

    @Autowired
    private PushSubSystemMapper pushSubSystemMapper;
    @Autowired
    private ImportLogMapper importLogMapper;
    @Autowired
    private ImportLogHistoryMapper importLogHistoryMapper;
    @Autowired
    private OtmEventService otmEventService;

    @Override
    public Page<OrderReleaseMidDTO> queryRouteRelease (Page<OrderReleaseMidDTO> page) {
        if (page == null) {
            throw new BaseException("page参数不能为空");
        }
        Map<String, Object> con = page.getCondition();
        if (con == null || con.isEmpty()) {
            throw new BaseException("参数不能为空");
        }
        Object oAll = con.get("queryAll");
        Object oTime = con.get("timeStamp");
        String queryAll = "";
        String timeStamp = "";
        if (oAll != null) {
            queryAll = oAll.toString();
        }
        if (oTime != null) {
            timeStamp = oTime.toString();
        }
        EntityWrapper<OrderReleaseMidDTO> ew = new EntityWrapper<>();
        if (StringUtils.isBlank(queryAll)
                || !TableStatusEnum.STATUS_Y.getCode().equalsIgnoreCase(queryAll)) {
            if (StringUtils.isBlank(timeStamp)) {
                throw new BaseException("参数不能为空");
            } else {
                Long longTime = null;
                try {
                    longTime = Long.valueOf(timeStamp);
                } catch (NumberFormatException e) {
                    throw new BaseException("时间戳格式不正确");
                }
                ew.gt("b.gmt_modified", new Date(longTime))
                        .orNew()
                        .gt("c.gmt_modified", new Date(longTime));
            }
        }
        ew.orderBy("c.order_route_gid", false);
        // 数据量大 分页
        List<OrderReleaseMidDTO> records = baseMapper.selectRouteReleaseByPage(page, ew);
        page.setRecords(records);
        return page;
    }

    @Override
    public Page<ShipmentInfo> queryShipmentMonitor (Page<ShipmentInfo> page) {
        Map<String, Object> condition = page.getCondition();
        EntityWrapper<ShipmentInfo> ew = new EntityWrapper<>();
        if (condition != null && !condition.isEmpty()) {
            if (Objects.nonNull(condition.get("shipmwnt_xid")) && StringUtils.isNotEmpty((String) condition.get("shipmwnt_xid"))) {
                ew.like("source_key", condition.get("shipmwnt_xid").toString());
            }
            if (Objects.nonNull(condition.get("startTime")) && StringUtils.isNotEmpty((String) condition.get("startTime"))) {
                ew.ge("gmt_create", this.stampToTime((String) condition.get("startTime")));
            }
            if (Objects.nonNull(condition.get("endTime")) && StringUtils.isNotEmpty((String) condition.get("endTime"))) {
                ew.le("gmt_create", this.stampToTime((String) condition.get("endTime")));
            }
        }
        ew.groupBy("source_key");
        ew.orderBy("gmt_create", false);
        List<ShipmentInfo> shipmentInfos = baseMapper.queryShipmentMonitor(page, ew);
        LOGGER.info("指令数据接口监控查询商品车结果：{}",shipmentInfos);
        if (null == shipmentInfos) {
            return null;
        }

        //调用WMS查询每个指令下商品车数量（有效状态）
        List<ShipmentInfo> list = this.queryShipmentCarVehicleQty(shipmentInfos);
        return page.setRecords(list);
    }

    @Override
    public Page<ShipmentInbound> queryShipmentInbound (Page<ShipmentInbound> page) {
        List<ShipmentInbound> shipmentInbounds = new ArrayList<>();
        LOGGER.info("指令数据接口监控查询WMS入库数据 开始ing");
        String jsonParam = JSONArray.toJSONString(page);
        LOGGER.info("指令数据接口监控查询WMS入库数据调用WMS jsonParam为：{}", jsonParam);
        String tmsQtyUrl = this.getTmsQtyUrl("WMS", "905");
        //调用wms获取入库信息
        String postJson = HttpClientUtil.postJson(tmsQtyUrl, null, jsonParam, 60000);
        LOGGER.info("查询WMS当天入库数据结果postJson为：{}",postJson);
        //获取返回值
        RestfulResponse<Page<ShipmentInbound>> restfulResponse = JSON.parseObject(postJson,
                new TypeReference<RestfulResponse<Page<ShipmentInbound>>>() {
        });
        if (Objects.nonNull(restfulResponse) && restfulResponse.getCode() == 0) {
            JSONObject object = JSONObject.parseObject(postJson);
            JSONObject jsonObject = object.getJSONObject("data");
            LOGGER.info("解析获取data的数据jsonObject为：{}", jsonObject);
            JSONArray jsonArray = jsonObject.getJSONArray("records");
            LOGGER.info("解析获取 records 的数据jsonArray为：{}", jsonArray);
            shipmentInbounds = JSONArray.parseArray(jsonArray.toString(), ShipmentInbound.class);
            LOGGER.info("指令数据接口监控查询WMS入库数据返回的结果shipmentInfos为：{}", shipmentInbounds);
        }
        LOGGER.info("指令数据接口监控查询WMS入库数据 结束");
        return page.setRecords(shipmentInbounds);
    }

    /**
     * 查询商品车数量
     *
     * @param shipmentInfos 指令信息
     */
    private List<ShipmentInfo> queryShipmentCarVehicleQty (List<ShipmentInfo> shipmentInfos) {
        List<ShipmentInfo> list = new ArrayList<>();
        LOGGER.info("指令数据接口监控查询商品车数量 开始ing");
        String jsonParam = JSONArray.toJSONString(shipmentInfos);
        LOGGER.info("指令数据接口监控查询商品数量调用运力平台jsonParam为：{}", jsonParam);
        String tmsQtyUrl = this.getTmsQtyUrl("WMS","90502");
        String postJson = HttpClientUtil.postJson(tmsQtyUrl, null, jsonParam, 60000);
        RestfulResponse<List<ShipmentInfo>> restfulResponse = JSON.parseObject(postJson,new TypeReference<RestfulResponse<List<ShipmentInfo>>>() {
                });
        if (Objects.nonNull(restfulResponse) && restfulResponse.getCode() == 0) {
            list = restfulResponse.getData();//把字符串转换成集合
            LOGGER.info("指令数据接口监控查询商品数量调用运力平台返回的结果shipmentInfos为：{}", shipmentInfos);
        }
        LOGGER.info("指令数据接口监控查询商品车数量 结束");
        return list;
    }

    /**
     * 获取url
     * @param system
     * @param systemCode
     * @return
     */
    private String getTmsQtyUrl (String system,String systemCode) {
        EntityWrapper<PushSubSystem> ew = new EntityWrapper<>();
        ew.eq("code", system);
        ew.eq("TYPE", systemCode);
        List<PushSubSystem> pushSubSystem = pushSubSystemMapper.selectList(ew);
        if (CollectionUtils.isEmpty(pushSubSystem)) {
            throw new BaseException("调用系统的请问路径未配置！");
        }
        return pushSubSystem.get(0).getUrl();
    }

    /**
     * 时间戳转换
     */
    public String stampToTime (String paramTime) {
        String returnTime = "";
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            long lt = new Long(paramTime);
            Date date = new Date(lt);
            returnTime = simpleDateFormat.format(date);
        } catch (Exception e) {
            throw new BaseException("请确认时间的查询条件格式是否正确【2019-02-01 00:00:00】");
        }
        return returnTime;

    }

    public Page<NewOrderReleaseMidDTO> queryRouteReleaseNew(Page<NewOrderReleaseMidDTO> page) {
        if (page == null) {
            throw new BaseException("page参数不能为空");
        }
        Map<String, Object> con = page.getCondition();
        if (con == null || con.isEmpty()) {
            throw new BaseException("参数不能为空");
        }
        Object oAll = con.get("queryAll");
        Object oTime = con.get("timeStamp");
        String queryAll = "";
        String timeStamp = "";
        if (oAll != null) {
            queryAll = oAll.toString();
        }
        if (oTime != null) {
            timeStamp = oTime.toString();
        }
        EntityWrapper<NewOrderReleaseMidDTO> ew = new EntityWrapper<>();
        if (StringUtils.isBlank(queryAll) || !TableStatusEnum.STATUS_Y.getCode().equalsIgnoreCase(queryAll)) {
            if (StringUtils.isBlank(timeStamp)) {
                throw new BaseException("参数不能为空");
            } else {
                Long longTime = null;
                try {
                    longTime = Long.valueOf(timeStamp);
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String format = sdf.format(new Date(longTime));
                    ew.gt("a.gmt_modified", format);
                } catch (NumberFormatException e) {
                    throw new BaseException("时间戳格式不正确");
                }
            }
        }
        // 数据量大 分页
        List<NewOrderReleaseMidDTO> records = baseMapper.selectRouteReleaseByPageNew(page, ew);
        page.setRecords(records);
        return page;
    }

    @Override
    public Page<InTransitDTO> queryInTransitInfo (Page<InTransitDTO> page) {
        Map<String, Object> condition = page.getCondition();
        EntityWrapper<InTransitDTO> ew = new EntityWrapper<>();
        if (Objects.nonNull(condition) && !condition.isEmpty()) {
            if (condition.containsKey("startDate") && StringUtils.isNotEmpty((String) condition.get("startDate"))) {
                ew.ge("position_date", condition.get("startDate"));
            }
            if (condition.containsKey("endDate") && StringUtils.isNotEmpty((String) condition.get("endDate"))) {
                ew.le("position_date", condition.get("endDate"));
            }
            if (condition.containsKey("plateNo") && StringUtils.isNotEmpty((String) condition.get("plateNo"))) {
                ew.le("plate_no", condition.get("plateNo"));
            }
        }
        List<InTransitDTO> inTransitDTOS = baseMapper.queryInTransitInfo(page,ew);
        return page.setRecords(inTransitDTOS);
    }

    @Override
    public void otmUpdateReleaseInfo (List<ReleaseDTO> param) {
        if (CollectionUtils.isEmpty(param)) {
            throw new BaseException("修改参数为空");
        }

        List<PushSubSystem> pushSubSystem = queryPushUrl();
        if (CollectionUtils.isEmpty(pushSubSystem)) {
            throw new BaseException("调用系统的请问路径未配置！");
        }

        for (ReleaseDTO releaseDTO : param) {
            String result = null;
            for (PushSubSystem pushUlr : pushSubSystem) {
                String resultCode = "SUCCESS";
                String message = null;
                LOGGER.info("{}otm修改运单信息返回数据为 开始ing", pushUlr.getUrl());
                String jsonParam = JSONArray.toJSONString(releaseDTO);
                String postJson = HttpClientUtil.postJson(pushUlr.getUrl(), null, jsonParam, 60000);
                LOGGER.info("{}otm修改运单信息返回数据为 jsonParam为：{}", jsonParam);
                RestfulResponse<String> restfulResponse = JSON.parseObject(postJson, new TypeReference<RestfulResponse<String>>() {
                });
                if (Objects.nonNull(restfulResponse) && restfulResponse.getCode() != 0) {
                    LOGGER.info("otm修改运单信息返回数据为返回的结果postJson为：{}", postJson);
                    resultCode = "ERROR";
                    message = restfulResponse.getMessage();
                }
                LOGGER.info("otm修改运单信息结束");
                if(StringUtils.isEmpty(postJson)){
                    resultCode = "ERROR";
                    message = "系统调用失败";
                }
                this.setUpdateReleaseLog(releaseDTO, resultCode, pushUlr.getCode(),message);
            }
        }
    }

    /**
     * 回单异常推送到OTM
     * @param podReasonDTO
     */
    @Override
    public String podReasonToOtm(PodReasonDTO podReasonDTO) {

        PushSubSystem pushSubSystem = new PushSubSystem();
        pushSubSystem.setCode("OTM");
        pushSubSystem.setType("210");
        PushSubSystem pushSubSystem1 = pushSubSystemMapper.selectOne(pushSubSystem);
        if (Objects.isNull(pushSubSystem1)) {
            throw new BaseException("调用系统的请问路径未配置！");
        }
        String result = reasonToOtm(pushSubSystem1.getUrl(), podReasonDTO);
        return result;

    }


    private String reasonToOtm(String url, PodReasonDTO podReasonDTO) {
        HashMap<String, String> otmParams = Maps.newHashMap();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        otmParams.put("recordDate", format.format(podReasonDTO.getRecordDate()));
        otmParams.put("orderGid",podReasonDTO.getOrderGid() );
        otmParams.put("details", podReasonDTO.getDetails());
        otmParams.put("abnormalPodReason", podReasonDTO.getAbnormalPodReason());
        otmParams.put("podReasonXid", podReasonDTO.getPodReasonXid());
        LOGGER.info("{}回单异常推送OTM 开始ing", url);
        String jsonParam = JSONArray.toJSONString(otmParams);

        Date startDate = new Date();
        LOGGER.info("{}回单异常推送OTM jsonParam为：{}", url, jsonParam);
        String postJson = HttpClientUtil.postJson(url, null, jsonParam, 60000);

        JSONObject jsonObject = JSON.parseObject(postJson);
        String messageType = jsonObject.get("messageType").toString();
        String message = null;
        if (Objects.nonNull(jsonObject.get("message"))) {
            message = jsonObject.get("message").toString();
        }

        RestfulResponse<Object> restfulResponse = new RestfulResponse<>();
        if (messageType.equals("success")) {
            restfulResponse.setCode(0);
            restfulResponse.setMessage(message);
        } else {

            restfulResponse.setCode(-1);
            restfulResponse.setMessage(message);
        }

        Date endDate = new Date();
        ExportLogHistory exportLogHistory = new ExportLogHistory();
        exportLogHistory.setTargertSys("otm");
        exportLogHistory.setExportKey(podReasonDTO.getOrderGid());
        exportLogHistory.setType("60");
        exportLogHistory.setInterfaceUrl(url);
        exportLogHistory.setExportStatus(messageType);
        exportLogHistory.setExportRemarks(message);
        exportLogHistory.setExportStartTime(startDate);
        exportLogHistory.setExportEndTime(endDate);


        Thread thread = new Thread() {
            public void run() {
                otmEventService.updateExportLogHistory(exportLogHistory, jsonParam);
            }
        };
        thread.start();
        return postJson;
    }


    @Override
    public void receiptStatus(Map<String, String> map) {
        PushSubSystem pushSubSystem = new PushSubSystem();
        pushSubSystem.setCode("TMS");
        pushSubSystem.setType("211");
        PushSubSystem pushSubSystem1 = pushSubSystemMapper.selectOne(pushSubSystem);
        if (Objects.isNull(pushSubSystem1)) {
            throw new BaseException("调用系统的请问路径未配置！");
        }
        String postJson = receiptStatusToTms(pushSubSystem1.getUrl(), map);
        receiptStatusLog(postJson,map,pushSubSystem1.getCode());
    }

    private void receiptStatusLog(String postJson, Map<String, String> map, String code) {
        ImportLogHistory importLogHistory = new ImportLogHistory();
        importLogHistory.setSourceSys("OTM");
        importLogHistory.setTargetSys(code);
        importLogHistory.setSourceKey(map.get("orderGid"));
        importLogHistory.setType("70");
        importLogHistory.setDataStorageKey(JSONArray.toJSONString(map));
        importLogHistory.setImportNote(postJson);
        importLogHistoryMapper.insert(importLogHistory);
    }

    private String receiptStatusToTms(String url, Map<String, String> map) {
        if (StringUtils.isEmpty(map.get("orderGid"))){
            throw  new BaseException("订单号不能为空");
        }
        if (StringUtils.isEmpty(map.get("podStatus"))){
            throw  new BaseException("回单状态不能为空");
        }
        HashMap<String, String> otmParams = Maps.newHashMap();
        otmParams.put("orderGid",map.get("orderGid"));
        otmParams.put("podStatus", map.get("podStatus"));
        LOGGER.info("{}回单状态推送TMS 开始ing", url);
        String jsonParam = JSONArray.toJSONString(otmParams);
        LOGGER.info("{}回单状态推送TMS jsonParam为：{}", url, jsonParam);
        String postJson="success";
        try {
            postJson = HttpClientUtil.postJson(url, null, jsonParam, 60000);

        } catch (BaseException e) {
            throw new BaseException("回单状态推送TMS失败");
        }
        return postJson;
    }

    private List<PushSubSystem> queryPushUrl () {
        List<String> codes = new ArrayList<>();
        codes.add("WMS");
        codes.add("TMS");
        List<String> types = new ArrayList<>();
        types.add("90503");
        EntityWrapper<PushSubSystem> ew = new EntityWrapper<>();
        ew.in("code", codes);
        ew.in("TYPE", types);
        return pushSubSystemMapper.selectList(ew);
    }

    /**
     * otm下发修改运单信息记录日志
     *  @param param  下发数据
     * @param resultCode 返回状态
     * @param code 系统
     * @param message 操作信息
     */
    private void setUpdateReleaseLog (ReleaseDTO param, String resultCode, String code, String message) {
        if (null != param) {
            ImportLogHistory importLogHistory = new ImportLogHistory();
            importLogHistory.setSourceSys("OTM");
            importLogHistory.setTargetSys(code);
            importLogHistory.setSourceKey(param.getShipmentGid());
            importLogHistory.setType(TableStatusEnum.STATUS_40.getCode());
            importLogHistory.setDataStorageKey(param.getReleaseGid());
            importLogHistory.setImportNote(JSONArray.toJSONString(param));
            importLogHistory.setImportStatus(resultCode);
            importLogHistory.setRemark(message);
            importLogHistoryMapper.insert(importLogHistory);
        }
    }

}
